package com.wdl.webserver.api;

import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.core.MediaType;

import org.influxdb.dto.QueryResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
@RequestMapping("/api/influx")
public class InfluxApiController {
	@Autowired
	public RestTemplate restTemplate;

	@Autowired
	private InfluxDBData influxDBData;

	@GetMapping(value = "/getCoordinate", produces = MediaType.APPLICATION_JSON)
	public List<Object> getCoordinate(@RequestParam("devId") String devId, HttpServletRequest request) {
		try {
			QueryResult qr = influxDBData
					.query("select * from gps_data where devid='" + devId + "' order by time desc limit 1");

			if (qr != null && qr.getResults() != null) {
				List<Object> c = qr.getResults().get(0).getSeries().get(0).getValues().get(0);

				return c;
			}

			return null;
		} catch (Exception e) {
			return null;
		}
	}

	@GetMapping(value = "/getCoordinateHistory", produces = MediaType.APPLICATION_JSON)
	public List<List<Object>> getCoordinateHistory(@RequestParam("devId") String devId,
			@RequestParam("start") long start, @RequestParam("end") long end, HttpServletRequest request) {
		try {
			long nowLong = new Date().getTime();

			long startH = (nowLong - start) / (60 * 60 * 1000l);
			long endH = (nowLong - end) / (60 * 60 * 1000l);

			QueryResult qr = influxDBData.query("select * from gps_data where devid='" + devId + "' and time>now()-"
					+ startH + "h and time<now()-" + endH + "h order by time desc limit 150");

			return qr.getResults().get(0).getSeries().get(0).getValues();
		} catch (Exception e) {
			return null;
		}
	}

	@GetMapping(value = "/getCoordinateByPersonId", produces = MediaType.APPLICATION_JSON)
	public List<Object> getCoordinateByPersonId(@RequestParam("personId") String personId, HttpServletRequest request) {
		try {
			QueryResult qr = influxDBData
					.query("select * from gps_data where personid='" + personId + "' order by time desc limit 1");

			if (qr != null && qr.getResults() != null) {
				List<Object> c = qr.getResults().get(0).getSeries().get(0).getValues().get(0);

				return c;
			}

			return null;
		} catch (Exception e) {
			return null;
		}
	}

	@GetMapping(value = "/getCoordinateHistoryByPersonId", produces = MediaType.APPLICATION_JSON)
	public List<List<Object>> getCoordinateHistoryByPersonId(@RequestParam("personId") String personId,
			@RequestParam("start") long start, @RequestParam("end") long end, HttpServletRequest request) {
		try {
			long nowLong = new Date().getTime();
			long startH = (nowLong - start) / (60 * 60 * 1000l);
			long endH = (nowLong - end) / (60 * 60 * 1000l);

			QueryResult qr = influxDBData.query("select * from gps_data where personid='" + personId
					+ "' and time>now()-" + startH + "h and time<now()-" + endH + "h order by time desc limit 150");

			return qr.getResults().get(0).getSeries().get(0).getValues();
		} catch (Exception e) {
			return null;
		}
	}

	@GetMapping(value = "/getHeart", produces = MediaType.APPLICATION_JSON)
	public List<Object> getHeart(@RequestParam("devId") String devId, HttpServletRequest request) {
		try {
			QueryResult qr = influxDBData
					.query("select * from heart_data where devid='" + devId + "' order by time desc limit 1");

			if (qr != null && qr.getResults() != null || qr.getResults().get(0) != null
					|| qr.getResults().get(0).getSeries() != null) {
				List<Object> c = qr.getResults().get(0).getSeries().get(0).getValues().get(0);

				return c;
			}

			return null;
		} catch (Exception e) {
			return null;
		}
	}

	@GetMapping(value = "/getHeartHistory", produces = MediaType.APPLICATION_JSON)
	public List<List<Object>> getHeartHistory(@RequestParam("devId") String devId, @RequestParam("start") long start,
			@RequestParam("end") long end, HttpServletRequest request) {
		try {
			long nowLong = new Date().getTime();
			long startH = (nowLong - start) / (60 * 60 * 1000l);
			long endH = (nowLong - end) / (60 * 60 * 1000l);

			QueryResult qr = influxDBData.query("select * from heart_data where devid='" + devId + "' and time>now()-"
					+ startH + "h and time<now()-" + endH + "h order by time desc limit 150");

			return qr.getResults().get(0).getSeries().get(0).getValues();
		} catch (Exception e) {
			return null;
		}
	}

	@GetMapping(value = "/getHeartByPersonId", produces = MediaType.APPLICATION_JSON)
	public List<Object> getHeartByPersonId(@RequestParam("personId") String personId, HttpServletRequest request) {
		try {
			QueryResult qr = influxDBData
					.query("select * from heart_data where personid='" + personId + "' order by time desc limit 1");

			if (qr != null && qr.getResults() != null || qr.getResults().get(0) != null
					|| qr.getResults().get(0).getSeries() != null) {
				List<Object> c = qr.getResults().get(0).getSeries().get(0).getValues().get(0);

				return c;
			}
			return null;
		} catch (Exception e) {
			return null;
		}
	}

	@GetMapping(value = "/getHeartHistoryByPersonId", produces = MediaType.APPLICATION_JSON)
	public List<List<Object>> getHeartHistoryByPersonId(@RequestParam("personId") String personId,
			@RequestParam("start") long start, @RequestParam("end") long end, HttpServletRequest request) {
		try {
			long nowLong = new Date().getTime();
			long startH = (nowLong - start) / (60 * 60 * 1000l);
			long endH = (nowLong - end) / (60 * 60 * 1000l);

			QueryResult qr = influxDBData.query("select * from heart_data where personid='" + personId
					+ "' and time>now()-" + startH + "h and time<now()-" + endH + "h order by time desc limit 150");

			return qr.getResults().get(0).getSeries().get(0).getValues();
		} catch (Exception e) {
			return null;
		}
	}
	
	@GetMapping(value = "/getHeartDataPerDaySeriesByPersonId", produces = MediaType.APPLICATION_JSON)
	public List<List<Object>> getMaxHeartPerDaySeriesByPersonId(@RequestParam("personId") String personId,
			@RequestParam("days") long days, HttpServletRequest request) {
		try {


			QueryResult qr = influxDBData.query("select max(heart),min(heart),median(heart),max(hv),min(hv),median(hv),max(lv),min(lv),median(lv) from heart_data where personid='" + personId
					+ "' and time>now()-" + days + "d group by time(24h)");

			return qr.getResults().get(0).getSeries().get(0).getValues();
		} catch (Exception e) {
			return null;
		}
	}


	@GetMapping(value = "/getHeartStatics", produces = MediaType.APPLICATION_JSON)
	public StatData getHeartStatics(@RequestParam("personId") String personId, @RequestParam("start") long start,
			@RequestParam("end") long end, HttpServletRequest request) {
		StatData sd = new StatData();
		try {

			long nowLong = new Date().getTime();
			long startH = (nowLong - start) / (60 * 60 * 1000l);
			long endH = (nowLong - end) / (60 * 60 * 1000l);
			String sql = "select max(heart) as maxheart,min(heart) as minheart,mean(heart) as meanheart,max(hv) as maxhv,min(hv) as minhv,mean(hv) as meanhv,max(lv) as maxlv,min(lv) as minlv,mean(lv) as meanlv from heart_data where personid='"
					+ personId + "' and time>now()-" + startH + "h and time<now()-" + endH + "h";

			sql = "select max(heart) from heart_data where personid='" + personId + "' and time>now()-" + startH
					+ "h and time<now()-" + endH + "h";
			QueryResult qr = influxDBData.query(sql);

			if (qr != null && qr.getResults() != null || qr.getResults().get(0) != null
					|| qr.getResults().get(0).getSeries() != null) {
				List<Object> c = qr.getResults().get(0).getSeries().get(0).getValues().get(0);

				sd.setMaxHeart(c.get(1));
				sd.setMaxHeartTime(c.get(0));
			}

			sql = "select min(heart) from heart_data where personid='" + personId + "' and time>now()-" + startH
					+ "h and time<now()-" + endH + "h";
			qr = influxDBData.query(sql);

			if (qr != null && qr.getResults() != null || qr.getResults().get(0) != null
					|| qr.getResults().get(0).getSeries() != null) {
				List<Object> c = qr.getResults().get(0).getSeries().get(0).getValues().get(0);

				sd.setMinHeart(c.get(1));
				sd.setMinHeartTime(c.get(0));
			}

			sql = "select max(hv) from heart_data where personid='" + personId + "' and time>now()-" + startH
					+ "h and time<now()-" + endH + "h";
			qr = influxDBData.query(sql);

			if (qr != null && qr.getResults() != null || qr.getResults().get(0) != null
					|| qr.getResults().get(0).getSeries() != null) {
				List<Object> c = qr.getResults().get(0).getSeries().get(0).getValues().get(0);

				sd.setMaxHv(c.get(1));
				sd.setMaxHvTime(c.get(0));
			}

			sql = "select min(hv) from heart_data where personid='" + personId + "' and time>now()-" + startH
					+ "h and time<now()-" + endH + "h";
			qr = influxDBData.query(sql);

			if (qr != null && qr.getResults() != null || qr.getResults().get(0) != null
					|| qr.getResults().get(0).getSeries() != null) {
				List<Object> c = qr.getResults().get(0).getSeries().get(0).getValues().get(0);

				sd.setMinHv(c.get(1));
				sd.setMinHvTime(c.get(0));
			}

			sql = "select max(lv) from heart_data where personid='" + personId + "' and time>now()-" + startH
					+ "h and time<now()-" + endH + "h";
			qr = influxDBData.query(sql);

			if (qr != null && qr.getResults() != null || qr.getResults().get(0) != null
					|| qr.getResults().get(0).getSeries() != null) {
				List<Object> c = qr.getResults().get(0).getSeries().get(0).getValues().get(0);

				sd.setMaxLv(c.get(1));
				sd.setMaxLvTime(c.get(0));
			}

			sql = "select min(lv) from heart_data where personid='" + personId + "' and time>now()-" + startH
					+ "h and time<now()-" + endH + "h";
			qr = influxDBData.query(sql);

			if (qr != null && qr.getResults() != null || qr.getResults().get(0) != null
					|| qr.getResults().get(0).getSeries() != null) {
				List<Object> c = qr.getResults().get(0).getSeries().get(0).getValues().get(0);

				sd.setMinLv(c.get(1));
				sd.setMinLvTime(c.get(0));
			}

			sql = "select mean(heart),mean(hv),mean(lv) from heart_data where personid='" + personId
					+ "' and time>now()-" + startH + "h and time<now()-" + endH + "h";
			qr = influxDBData.query(sql);

			if (qr != null && qr.getResults() != null || qr.getResults().get(0) != null
					|| qr.getResults().get(0).getSeries() != null) {
				List<Object> c = qr.getResults().get(0).getSeries().get(0).getValues().get(0);

				sd.setMeanHeart(c.get(1));
				sd.setMeanHv(c.get(2));
				sd.setMeanLv(c.get(3));
			}

			return sd;
		} catch (Exception e) {
			e.printStackTrace();
			return sd;
		}
	}
}
